package com.gh.ok.api

import android.util.Log
import com.aleyn.cache.CacheManager
import com.aleyn.cache.NetCacheInterceptor
import com.gh.ok.const.Const.BASE_URL
import com.ok.common.adapter.FlowAdapterFactory
import com.ok.common.base.AppContext
import okhttp3.ConnectionPool
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import com.ok.common.ext.defaultMoshiAdapter
import java.util.concurrent.TimeUnit

/**
 * RetrofitClient
 * - 支持自定义Header
 * - 支持自定义缓存目录/大小
 */
class RetrofitClient {

    companion object {
        fun getInstance() = SingletonHolder.INSTANCE
        private lateinit var retrofit: Retrofit
    }

    private object SingletonHolder {
        val INSTANCE = RetrofitClient()
    }

    init {

        retrofit = Retrofit.Builder()
            .client(getOkHttpClient())
            .addCallAdapterFactory(FlowAdapterFactory.create(true))
            .addConverterFactory(MoshiConverterFactory.create(defaultMoshiAdapter))
            .baseUrl(BASE_URL)
            .build()

    }

    private fun getOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(15L, TimeUnit.SECONDS)
            .writeTimeout(20L, TimeUnit.SECONDS)
            .readTimeout(20L, TimeUnit.SECONDS)
            .connectionPool(ConnectionPool(50, 5, TimeUnit.MINUTES))
            .addInterceptor(getHeaderInterceptor())
            .addInterceptor(
                NetCacheInterceptor(
                    CacheManager(
                        AppContext.cacheDir, maxSize = 50 * 1024 * 1024,
                    )
                )
            )
            .addInterceptor(getLoggerInterceptor())
            .build()
    }

    /**
     * 请求头拦截器
     */
    private fun getHeaderInterceptor(): Interceptor {
        return Interceptor { chain: Interceptor.Chain ->
            val original: Request = chain.request()
            val requestBuilder = original.newBuilder()
                .header("Content-Type", "application/json; charset=UTF-8")
                .header("Accept", "application/json")
                .method(original.method, original.body)

            chain.proceed(requestBuilder.build())
        }
    }

    /**
     * 日志拦截器
     *
     * @return
     */
    private fun getLoggerInterceptor(): HttpLoggingInterceptor {
        return HttpLoggingInterceptor { message: String ->
            Log.e("HTTP", "--->$message")
        }.setLevel(HttpLoggingInterceptor.Level.BODY)
    }

    fun <T> create(service: Class<T>?): T =
        retrofit.create(service!!) ?: throw RuntimeException("Api service is null!")

}